import pandas as pd
from flask import Flask,request,redirect,url_for,render_template  # 从flask包中导入flask类
from datetime import datetime
app = Flask(__name__)
# # 使用装饰器定义路由
# # @app.route('/')表示这个函数待处理URL('/')的请求
# @app.route('/')
# def hello_world(): # put application's code here
#     # 这个函数将在访问根URL时被调用
#     # 它返回一个字符串，这个字符串会被发送到客户端浏览器
#     return ('hello world')
#
# # 一、定义URL
#
# # 1、定义一个无参数的URL
# @app.route('/profile')  # 所以把route称为路由，通过写入具体的字符串，网站能够进行跳转
# def profile():
#     return '这是个人中心'
#

# # 2、定义有参数的URL
# @app.route('/blog/<blog_id>')
# def blog_detail(blog_id):
#     return "你查找的博客id为：%s"  % blog_id

#
# # 3、指定blog_id 为int类型
# @app.route('/blog/<int:blog_id>')
# def blog_detail(blog_id):
#     return "你查找的博客id为：%s"  % blog_id
#
# # 4、分类
# @app.route('/blog/list/<any(python,flask,django):category>')
# def blog_list_with_category(category):
#     return '你获得的博客分类为：%s' % category
#
# # 5、传递两个参数
# @app.route('/blog/list/<int:use_id>/<int:page>')
# def blog_list(use_id,page):
#     return '你查找的用户为：%s,博客分页为：%s' %(use_id,page)
#
# # 6
# @app.route('/blog/list_l/<int:use_id>')
# @app.route('/blog/list_l/<int:use_id>/<int:page>')
# def blog_list_1(use_id,page=1):
#     return '你查找的用户为：%s,博客分页为：%s' %(use_id,page)
#
# # 7、通过查询字符串的方式传递参数，不需要在定义URL和视图函数时提前定义好参数，参数可以通过Flask中的request.args对象获取
# # blog/list?ues_id=11&page=8
# @app.route('/blog/list')
# def blog_list_query_str():
#     use_id = request.args.get("use_id")
#     page = request.args.get("page")
#     return '你查找的用户id为：%s,博客分类为：%s' % (use_id,page)
# # 其中request是一个线程隔离的全局对象，
# # request.args是一个继承自dict的对象，保存了当前请求的查询字符串的参数，并被解析为键值对的形式存在
#
#
# # 二、HTTP请求方法
#
#
# @app.route('/blog/add',methods=['POST'])
# def blog_add():
#     return '使用plot方法添加博客'
#
# @app.route('/blog/add/post/get',methods=['POST','GET'])
# def blog_add_post_get():
#     if request.method == 'GET':
#         return '使用get方法添加博客'
#     else:
#         return '使用post方法添加博客'


# # 三、页面重定向
# # 重定向在页面中体现的操作是，浏览器会从一个页面自动跳转到另外一个页面
#
# # 登录重定向
# @app.route('/login')
# def login():
#     return 'login page'
# # 当用户正确输入/profile？name=admin时，显示名字，否则跳转回登录页面
# @app.route('/profile')
# def profile():
#     name = request.args.get('name')
#
#     if not name:
#         return redirect('/login')
#         # 如果没有name，说明没有登录，则重定向到登录页面
#     else:
#         return name


# 四、构造URL

@app.route('/blog_detail/<int:blog_id>')
def blog_detail_list(blog_id):
    return '你查找的博客id为：%s' % blog_id

@app.route('/urlfor')
def get_url_for():
    url = url_for('blog_detail_list',blog_id=2,use='admin')
    return url

# 五、JinJa2模板
@app.route('/')
def index():
    return render_template('index.html')

# 1、渲染变量
@app.route('/variable')
def variable():
    hobby = '竞赛论文'
    return render_template('variable.html',hobby=hobby)


# 编写echo_message
@app.route('/echomsg/<msg_id>')
def echo_message(msg_id):
    return render_template('message.html',msg_id=msg_id,usename='李四')

#
class User:
    def __init__(self,username,email):
        self.username = username
        self.email = email

@app.route('/variableMessage')
def variableMessage():
    hobby = '书法'
    person = {
        "name":"张三",
        "age":18
    }
    user = User("麻子","xx@qq.com")
    return render_template("variable.html",hobby=hobby,person=person,user=user)

@app.route('/variableMessage1')
def variableMessage1():
    hobby = "阅读"
    person = {
        "name": "张三",
        "age": 18
    }
    user = User("李四","x@qq.com")
    context = {
        "hobby": hobby,
        "person": person,
        "user": user
    }
    return render_template("variable.html",**context)


# 2、过滤器
# 2.1、自定义过滤器
# value就是以后使用过滤器的时候，前面的管道符号。前面的值作为它的第一个参数传给它
# 第二个参数format，因为是时间格式操作，将datetime这种类型格式化成字符串
def datetime_format(value,format="%Y-%m-%d %H:%M:%S"):
    return value.strftime(format)

# 时间格式化函数定义或过滤器，这个过滤器的名称就是“dformat”
app.add_template_filter(datetime_format,"dformat")  # 这个dformat要写在模板中

@app.route("/filter")
def filter():
    user = User(username="张三xxxx",email="abc@qq.com")
    mytime = datetime.now() # 获取现在的时间
    return render_template("filter.html",user=user,mytime=mytime)

# 2.2、内置过滤器
@app.route('/filter_method')
def filter_method():
    context = {
        'name':'多个信息'
    }
    # 设置传递给模板的变量
    # 使用render_template渲染templates文件夹下的filter_method.html模板
    return render_template("filter_method.html",**context)


# 3、测试器
@app.route('/test')
def test():
    context = {
        'user':'John Doe' # 如果需要测试未定义的情况，可以将这一行注释掉
    }
    return render_template('test.html',**context)
    # 设置传递给模板的变量

# 4、JinJa2中的控制语句

# 4.1、if判断语句
@app.route('/if')
def if_statement():
    age = 18
    return render_template("if.html",age=age)


# 4.2、for循环语句
@app.route("/for")
def for_statement():
    books = [
        {
            "name":"三国演义",
            "author":"罗贯中",
            "price":100
        },
        {
            "name":"水浒传",
            "author": "施耐庵",
            "price": 99
        },
        {
            "name": "红楼梦",
            "author": "曹雪芹",
            "price": 101
        },
        {
            "name": "西游记",
            "author": "吴承恩",
            "price": 102
        }
    ]
    return render_template("for.html",books=books)


# 4.2.1、for循环中的变量
# loop.index,loop.cycle
books_list = [
    {'name':'python编程','author':'mark','price':79.00},
    {'name':'深入浅出的计算机组成原理','author':'侯捷','price':59.00},
    {'name':'算法导论','author':'Thomas','price':129.00},
    {'name':'设计模式','author':'Erich，Richard等','price':99.00},
    {'name':'JavaScript高级程序设计','author':'Nicholas','price':69.00},
    {'name':'你不知道的JavaScript','author':'kyle','price':89.00},
    {'name':'head frist设计模式','author':'Eric','price':49.00},
    {'name':'重构','author':'Martin','price':39.00},
    {'name':'clean code','author':'Robert','price':109.00},
    {'name':'架构整洁之道','author':'Robert','price':139.00},
]

@app.route('/books')
def show_books():
    return render_template('books.html',books=books_list)

@app.route('/books2')
def show_books2():
    return render_template('books2.html',books=books_list)


# 5、模板结构
# 5.1、宏
@app.route('/macros')
def show_macros():
    return render_template('macros_test.html')
# 假设我们有一个处理表单提交的简单路由
# 定义了一个处理POST请求的路由，当用户向/submit提交表单时，会调用submit_form函数
@app.route('/submit',methods=['POST'])
def submit_form():
    username = request.form.get('username')
    password = request.form.get('password')
    return f"提交的用户名：{username}, 密码：{password}"


# 5.2、import语句
@app.route('/main')
def forms_main():
    username = 'join_doe'
    password = 'abc123'
    comment = 'this is success.'
    return render_template('main.html',username=username,password=password,comment=comment)


# 5.3、动态生成表单
@app.route('/main1')
def forms_main1():
    return render_template('main1.html')

@app.route('/save1',methods=['POST'])
def save_data1():
    # 获取表单数据
    username = request.form.get('username')
    password = request.form.get('password')
    comment = request.form.get('comment')

    # 创建或读取现有的excel文件
    file_path = 'data/users.xlsx' # 现在并没有这个表格文件
    try:
        df = pd.read_excel(file_path)
    except FileNotFoundError:
        df = pd.DataFrame(columns=['Username','Password','Comment','Timestamp'])

        # 添加新数据
        new_data = {
            'Username':[username],
            'Password':[password],
            'Comment':[comment],
            'Timestamp':[datetime.now()]
        }
        df_new = pd.DataFrame(new_data)
        df = pd.concat([df,df_new],ignore_index=True)
        # 保存到excel文件
        with pd.ExcelWriter(file_path,engine='openpyxl') as writer:
            df.to_excel(writer,index=False)
    # 重定向回主页面
    return redirect(url_for('forms_main1'))



# 5.4、通过from…import.…as…from和m…import…形式导入
@app.route('/main2')
def forms_main2():
    return render_template('main2.html')

@app.route('/save2',methods=['POST'])
def save_data2():
    # 获取表单数据
    username = request.form.get('username')
    password = request.form.get('password')
    comment = request.form.get('comment')
    form_name = request.form.get('form_name', 'unknown')  # 获取表单名称，默认值为 'unknown'

    # 创建或读取现有的excel文件
    file_path = 'data/users.xlsx'
    try:
        df = pd.read_excel(file_path)
    except FileNotFoundError:
        df = pd.DataFrame(columns=['Form name','Username','Password','Comment','Timestamp'])

        # 添加新数据
        new_data = {
            'Form name': [form_name],
            'Username':[username],
            'Password':[password],
            'Comment':[comment],
            'Timestamp':[datetime.now()]
        }
        df_new = pd.DataFrame(new_data)
        df = pd.concat([df,df_new],ignore_index=True)
        # 保存到excel文件
        with pd.ExcelWriter(file_path,engine='openpyxl') as writer:
            df.to_excel(writer,index=False)

    # 重定向回主页面
    return redirect(url_for('forms_main2'))

if __name__ == '__main__':
    # 如果这个脚本被直接运行（而不是被导入），那么就运行flask应用
    # debug=True 启动调试模式，这在开发中很有用
    # - 它会在代码变更时自动重新加载应用
    # - 它会发生错误时显示详细的错误信息
    app.run(debug=True)